<template>
    <!-- 代码编辑器 -->
    <div class="monaco-editor">
        <div id="container" class="container" ref="container"></div>
    </div>
</template>
<script>
// import * as monaco from 'monaco-editor';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
export default {
    props: {
        editorOptions: {
            type: Object,
            default: function() {
                return {
                    // 编辑器初始显示文字
                    value: '',
                    // 语言支持自行查阅demo
                    language: 'json',
                    // 自动布局
                    automaticLayout: true,
                    // 代码可分小段折叠
                    foldingStrategy: 'indentation',
                    // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
                    autoClosingBrackets: 'never',
                    // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
                    autoClosingDelete: 'never',
                    // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
                    autoClosingQuotes: 'never',
                    // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
                    autoIndent: 'full',
                    comments: {
                        // 插入行注释时忽略空行。默认为真。
                        ignoreEmptyLines: true,
                        // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
                        insertSpace: true
                    },
                    // 光标动画样式
                    cursorBlinking: 'Solid',
                    // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
                    cursorSmoothCaretAnimation: false,
                    // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
                    cursorSurroundingLines: 0,
                    // "default" | "all" 光标环绕样式
                    cursorSurroundingLinesStyle: 'default',
                    // <=25 光标宽度
                    cursorWidth: 2,
                    minimap: {
                        // 是否启用预览图 // 关闭代码缩略图
                        enabled: false
                    },
                    // 是否应围绕概览标尺绘制边框
                    overviewRulerBorder: false,
                    // 是否启用代码折叠
                    folding: true,
                    // 设置编辑器是否可以滚动到最后一行之后
                    scrollBeyondLastLine: false,
                    // 当前行突出显示方式  "all" | "line" | "none" | "gutter"
                    renderLineHighlight: 'all',
                    // 官方自带三种主题vs, hc-black, or vs-dark
                    theme: 'vs',
                    // 右键菜单是否启用
                    contextmenu: false,
                    quickSuggestions: true,
                    suggestOnTriggerCharacters: true,
                    acceptSuggestionOnEnter: true
                }
            }
        }
    },
    data() {
        return {
            defaultEditorOptions: {
                // 编辑器初始显示文字
                value: '',
                // 语言支持自行查阅demo
                language: 'json',
                // 自动布局
                automaticLayout: true,
                // 代码可分小段折叠
                foldingStrategy: 'indentation',
                // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
                autoClosingBrackets: 'never',
                // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
                autoClosingDelete: 'never',
                // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
                autoClosingQuotes: 'never',
                // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
                autoIndent: 'full',
                comments: {
                    // 插入行注释时忽略空行。默认为真。
                    ignoreEmptyLines: true,
                    // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
                    insertSpace: true
                },
                // 光标动画样式
                cursorBlinking: 'Solid',
                // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
                cursorSmoothCaretAnimation: false,
                // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
                cursorSurroundingLines: 0,
                // "default" | "all" 光标环绕样式
                cursorSurroundingLinesStyle: 'default',
                // <=25 光标宽度
                cursorWidth: 2,
                minimap: {
                    // 是否启用预览图 // 关闭代码缩略图
                    enabled: false
                },
                // 是否应围绕概览标尺绘制边框
                overviewRulerBorder: false,
                // 是否启用代码折叠
                folding: true,
                // 设置编辑器是否可以滚动到最后一行之后
                scrollBeyondLastLine: false,
                // 当前行突出显示方式  "all" | "line" | "none" | "gutter"
                renderLineHighlight: 'all',
                // 官方自带三种主题vs, hc-black, or vs-dark
                theme: 'vs',
                // 右键菜单是否启用
                contextmenu: false,
                quickSuggestions: true,
                suggestOnTriggerCharacters: true,
                acceptSuggestionOnEnter: true
            },
            monacoEditor: null
        }
    },
    watch: {
        editorOptions: {
            handler(newVal) {
                if (newVal && newVal.value) {
                    this.setDefaultValue(newVal.value)
                }
            },
            deep: true,
            immediate: true
        }
    },
    mounted() {
        this.initEditor()
    },
    methods: {
        /**
         * 初始化编辑器
         */
        initEditor() {
            let that = this
            if (that.$refs.container) {
                that.$refs.container.innerHTML = ''
            }
            monaco.editor.remeasureFonts()
            that.monacoEditor = monaco.editor.create(
                that.$refs.container,
                Object.assign(this.defaultEditorOptions, this.editorOptions)
            )
            that.monacoEditor.onDidChangeModelContent(function() {
                //编辑器内容changge事件
                let codesCopy = that.monacoEditor.getValue()
                that.$emit('onCodeChange', codesCopy)
            })
            //编辑器随窗口自适应
            window.addEventListener('resize', function() {
                that.initEditor()
            })
            this.formartCode()
        },
        /**
         * 格式化代码
         */
        formartCode() {
            this.monacoEditor.getValue()
            this.monacoEditor.trigger(null, 'editor.action.formatDocument')
        },
        /**
         * 修改默认显示的值
         */
        setDefaultValue(val) {
            if (this.monacoEditor) {
                this.monacoEditor.setValue(val) // 调用monaco组件的方法，设置monaco编辑器的值
            } else {
                return
            }
            this.formartCode()
        }
    },
    beforeDestroy() {
        if (this.monacoEditor) {
            this.monacoEditor.dispose()
        }
    }
}
</script>
<style lang="scss" scoped>
.monaco-editor {
    width: 100%;
    height: 100%;
    .container {
        width: 100%;
        height: 100%;
    }
    .view-line {
        letter-spacing: 0.5px !important;
        font-family: inherit !important;
    }
}
</style>
